<?php

namespace App\Console\Commands;

use App\Models\MonitorModel;
use App\Models\PreCouponSendLogModel;
use App\Models\PreCouponSendTaskModel;
use App\Models\ReceiversModel;
use App\Repositories\ActivitiesRepository;
use App\Repositories\CouponReceiveRepository;
use App\Repositories\CouponSendLogRepository;
use App\Repositories\PreCouponSendTaskRepository;
use App\Services\Wx\CouponService;
use Carbon\Carbon;
use Illuminate\Console\Command;

class WxCouponAutoSend extends Command
{

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'wx:coupon:auto:send';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '微信代金券自动发放';


    /**
     * Execute the console command.
     */
    public function handle()
    {
        $this->createSendActivities();
        sleep(5);
        //处理发券记录
        $this->handleAutoSendLog();

        echo "执行完毕";

        return true;
    }


    /**
     * 生成活动发券任务
     * @return true
     */
    public function createSendActivities()
    {
        $nowDate = Carbon::now()->toDateTimeString();
        $nowDayStart = date('Y-m-d 00:00:00');
        $nowDayEnd = date( 'Y-m-d 23:59:59');
        //获取所有进行中的活动
        $activityList = MonitorModel::query()
            ->where('status', MonitorModel::STATUS_ONLINE)
            ->where('type', MonitorModel::COUPON_TYPE)
            ->where('receive_date_start', '<=', $nowDate)
            ->where('receive_date_end', '>=', $nowDate)
            ->select(['id', 'stock_ids', 'coupon_daily_receive_num'])
            ->get()
            ->toArray();
        foreach ($activityList as $activityInfo) {
            $activityId = $activityInfo['id'];
            $activitiesRepo = new ActivitiesRepository();
            $stockIds = $activitiesRepo->getStockIdsByActivityId($activityInfo['stock_ids']);
            if (!$stockIds) {
                continue;
            }
            //若当日该活动已触发过自动发券任务，则略过
            $taskExist = PreCouponSendTaskModel::query()
                ->where('activity_id', $activityId)
                ->where('is_auto', PreCouponSendTaskModel::IS_AUTO_YES)
                ->where('created_at', '>=', $nowDayStart)
                ->where('created_at', '<=', $nowDayEnd)
                ->count();
            if($taskExist) {
                continue;
            }
            $sendRes = $this->saveSendActivityReceiverLog($activityId, $stockIds, $activityInfo['coupon_daily_receive_num']);
        }

        return true;
    }

    /**
     * 保存待发送任务日志
     * @param $activityId
     * @param $stockIds
     * @param $dailyReceiveNum //每日发券数量
     * @return void
     */
    public function saveSendActivityReceiverLog($activityId, $stockIds, $dailyReceiveNum = 1)
    {
        $sendReceiverList = [];
        $nowDate = Carbon::now()->toDateTimeString();
        $lastId = 0;
        $pageSize = 200;
        while (true) {
            //获取需券的受助人
            $receiverList = ReceiversModel::query()
                ->where('receiver_status', ReceiversModel::RECEIVE_STATUS_ENABLED)
                ->where('auth_status', ReceiversModel::AUTHED_STATUS)
                ->where('activity_id', $activityId)
                ->where('type', ReceiversModel::TYPE_COUPON)
                ->where('auth_end_date', '>', date('Y-m-d H:i:s'))
                ->where('id', '>', $lastId)
                ->limit($pageSize)
                ->select(['id', 'real_id', 'openid'])
                ->get()
                ->toArray();
            if (!$receiverList) {
                break;
            }
            foreach ($receiverList as $val) {
                $lastId = $val['id'];
                $sendReceiverList[] = $val;
            }
        }
        $sendReceiverNum = count($sendReceiverList);
        //生成任务主信息
        $preCouponSendLogTaskRepo = new PreCouponSendTaskRepository();
        $taskId = $preCouponSendLogTaskRepo->addTask($activityId, $stockIds, $sendReceiverNum);
        //插入任务明细
        $saveData = [];
        foreach ($sendReceiverList as $k => $val) {
            $data = [
                'activity_id'  => $activityId,
                'task_id'      => $taskId,
                'receiver_id'  => $val['id'],
                'openid'       => $val['openid'],
                'is_auto'      => PreCouponSendLogModel::AUTO_SEND,
                'status'       => PreCouponSendLogModel::STATUS_NOT_SEND,
                'need_send_at' => $nowDate,
                'created_at'   => $nowDate,
            ];
            //根据活动设置的每日发券数量，每个受助人插入对应数量的待发送记录
            for ($i = 0; $i < $dailyReceiveNum; $i++) {
                $saveData[] = $data;
            }
            //每20条 或 最后一条，批量插入一次
            if (count($saveData) >= 20 || $k == $sendReceiverNum - 1) {
                PreCouponSendLogModel::query()
                    ->insert($saveData);
                $saveData = [];
            }
        }

        return true;
    }

    /**
     * 处理自动发券
     * @return true
     */
    public function handleAutoSendLog()
    {
        //获取任务列表
        $taskList = PreCouponSendTaskModel::query()
            ->where('is_auto', PreCouponSendTaskModel::IS_AUTO_YES)
            ->where('status', PreCouponSendTaskModel::STATUS_WAITING)
            ->get()
            ->toArray();
        $couponService = new CouponService();
        foreach ($taskList as $taskInfo) {
            //处理本次发券任务明细
            $couponService->distributeBySendTask($taskInfo['id'], $taskInfo['activity_id']);
        }

        return true;
    }

}